﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DotNet.Practico1.UI.Presentation;
using DotNet.Practico1.UI.Model;
using DotNet.Practico1.UI.Support;

namespace DotNet.Practico1.UI
{
    public partial class frmMain : Form, IMainView
    {
        #region Protected

        protected MainPresenter _presenter;
        protected IEnumerable<UIContact> _contacts;
        protected IEnumerable<UIContact> _foundContacts;
        protected IEnumerable<UIAddress> _foundAddresses;
        protected IEnumerable<UIPhone> _foundPhones;
        protected IEnumerable<UIEmail> _foundEmails;
        protected IEnumerable<UIGroup> _foundGroups;
        protected IEnumerable<UIContact> _infoContacts;
        protected IEnumerable<UIAddress> _infoAddresses;
        protected IEnumerable<UIPhone> _infoPhones;
        protected IEnumerable<UIEmail> _infoEmails;
        protected IEnumerable<UIGroup> _infoGroups;
        protected Font normalFont = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Regular);
        protected Font boldFont = new Font("Microsoft Sans Serif", 8.25f, FontStyle.Bold);
        protected IEnumerable<TypesDTO> _phoneTypes;
        protected IEnumerable<TypesDTO> _emailTypes;
        protected IEnumerable<TypesDTO> _addressTypes;
        protected IEnumerable<TypesDTO> _groups;
        protected IEnumerable<TypesDTO> _contactGroups;

        #endregion

        #region Properties

        public IEnumerable<Model.UIContact> Contacts
        {
            get { return _contacts; }
            set { _contacts = value; }
        }

        public IEnumerable<TypesDTO> PhoneTypes
        {
            get { return _phoneTypes; }
            set { _phoneTypes = value; }
        }

        public IEnumerable<TypesDTO> EmailTypes
        {
            get { return _emailTypes; }
            set { _emailTypes = value; }
        }

        public IEnumerable<TypesDTO> AddressTypes
        {
            get { return _addressTypes; }
            set { _addressTypes = value; }
        }
        public IEnumerable<TypesDTO> Groups
        {
            get { return _groups; }
            set { _groups = value; }
        }
        public IEnumerable<TypesDTO> ContactGroups
        {
            get { return _contactGroups; }
            set { _contactGroups = value; }
        }

        public bool ShowSearchPanel { set { this.splitContainer2.Panel2Collapsed = value; } }
        public bool ShowInfoPanel { set { this.splitContainer2.Panel1Collapsed = value; } }
        public string SaveCSVFileName { get { return sfdExport.FileName; } }

        #endregion

        #region Search Parameters

        public string SearchPhone { get { return txtSearchPhoneNumber.Text; } }
        public short SearchPhoneType { get { return Convert.ToInt16(cbxSearchPhoneType.SelectedValue); } }
        public string SearchFirstName { get { return txtSearchContactFrirstName.Text; } }
        public string SearchLastName { get { return txtSearchContactLastName.Text; } }
        public string SearchEmail { get { return txtSearchEmail.Text; } }
        public short SearchEmailType { get { return Convert.ToInt16(cbxSearchEmailType.SelectedValue); } }
        public DateTime SearchStartDate
        {
            get
            {
                if (chkSearchToday.Checked)
                    return DateTime.Now;
                if (chkSearchThisWeek.Checked)
                    return DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
                return DateTime.Now.AddMonths(1).StartOfMonth();

            }
        }
        public DateTime SearchEndDate
        {
            get
            {
                if (chkSearchToday.Checked)
                    return DateTime.Now;
                if (chkSearchThisWeek.Checked)
                    return DateTime.Now.EndOfWeek(DayOfWeek.Sunday);
                return DateTime.Now.AddMonths(1).EndOfMonth();

            }
        }

        #endregion

        #region Search Results

        public IEnumerable<UIContact> FoundContacts { get { return _foundContacts; } set { _foundContacts = value; } }
        public IEnumerable<UIAddress> FoundAddresses { get { return _foundAddresses; } set { _foundAddresses = value; } }
        public IEnumerable<UIPhone> FoundPhones { get { return _foundPhones; } set { _foundPhones = value; } }
        public IEnumerable<UIEmail> FoundEmails { get { return _foundEmails; } set { _foundEmails = value; } }
        public IEnumerable<UIGroup> FoundGroups { get { return _foundGroups; } set { _foundGroups = value; } }

        public UIContact FoundContact
        {
            get
            {
                if (lbxFoundContacts.SelectedValue != null)
                    return (UIContact)lbxFoundContacts.SelectedValue;
                return null;
            }
        }
        public UIAddress FoundAddress
        {
            get
            {
                if (lbxFoundAddresses.SelectedValue != null)
                    return (UIAddress)lbxFoundAddresses.SelectedValue;
                return null;
            }
        }
        public UIPhone FoundPhone
        {
            get
            {
                if (lbxFoundPhones.SelectedValue != null)
                    return (UIPhone)lbxFoundPhones.SelectedValue;
                return null;
            }
        }
        public UIEmail FoundEmail
        {
            get
            {
                if (lbxFoundEmails.SelectedValue != null)
                    return (UIEmail)lbxFoundEmails.SelectedValue;
                return null;
            }
        }
        public UIGroup FoundGroup
        {
            get
            {
                if (lbxFoundGroups.SelectedValue != null)
                    return (UIGroup)lbxFoundGroups.SelectedValue;
                return null;
            }
        }
        public string FoundContactFirstName { set { lblFoundContactFirstName.Text = value; } }
        public string FoundContactLastName { set { lblFoundContactLastName.Text = value; } }
        public DateTime FoundContactBirthDate { set { lblFoundContactBirthDate.Text = value.ToLongDateString(); } }
        public string FoundContactComments { set { lblFoundContactComment.Text = value; } }
        public byte[] FoundContactImage { set { pbxFindContactPhoto.Image = Utils.BinaryToImage(value); } }

        public string FoundAddressStreet { set { lblFoundAddress.Text = value; } }
        public string FoundAddressCity { set { lblFoundCity.Text = value; } }
        public string FoundAddressPostalCode { set { lblFoundPostalCode.Text = value; } }
        public string FoundAddressCountry { set { lblFoundCountry.Text = value; } }
        public string FoundPhoneNumber { set { lblFoundPhone.Text = value; } }
        public string FoundPhoneType { set { lblFoundPhoneType.Text = value; } }
        public string FoundEmailAddress { set { lblFoundEmail.Text = value; } }
        public string FoundEmailType { set { lblFoundEmailType.Text = value; } }
        public string FoundGroupMemberCount { set { lblFoundGroupMemberCount.Text = value; } }

        #endregion

        #region Edit Information
        public int SelectedGroup
        {
            get
            {
                if (lbxGroups.SelectedValue != null)
                    return (int)lbxGroups.SelectedValue;
                return -1;
            }
            set { lbxGroups.SelectedValue = value; }
        }
        public int SelectedInfoGroup
        {
            get
            {
                if (cbxGroups.SelectedValue != null)
                    return (int)cbxGroups.SelectedValue;
                return -1;
            }
            set { cbxGroups.SelectedValue = value; }
        }
        public IEnumerable<UIContact> InfoContacts { get { return _infoContacts; } set { _infoContacts = value; } }
        public IEnumerable<UIAddress> InfoAddresses { set { _infoAddresses = value; } }
        public IEnumerable<UIPhone> InfoPhones { set { _infoPhones = value; } }
        public IEnumerable<UIEmail> InfoEmails { set { _infoEmails = value; } }
        public IEnumerable<UIGroup> InfoGroups { set { _infoGroups = value; } }
        public string ImagePath { get { return ofdInfoPicture.FileName; } }

        public UIAddress InfoAddress
        {
            get
            {
                if (lbxInfoAddresses.SelectedValue != null)
                    return (UIAddress)lbxInfoAddresses.SelectedValue;
                return null;
            }
        }
        public UIPhone InfoPhone
        {
            get
            {
                if (lbxInfoPhones.SelectedValue != null)
                    return (UIPhone)lbxInfoPhones.SelectedValue;
                return null;
            }
        }
        public UIEmail InfoEmail
        {
            get
            {
                if (lbxInfoEmails.SelectedValue != null)
                    return (UIEmail)lbxInfoEmails.SelectedValue;
                return null;
            }
        }
        public UIGroup InfoGroup
        {
            get
            {
                if (lbxInfoGroups.SelectedValue != null)
                    return (UIGroup)lbxInfoGroups.SelectedValue;
                return null;
            }
        }

        public string InfoContactFirstName
        {
            get { return txtInfoFirstName.Text; }
            set { txtInfoFirstName.Text = value; }
        }
        public string InfoContactLastName
        {
            get { return txtInfoLastName.Text; }
            set { txtInfoLastName.Text = value; }
        }
        public DateTime InfoContactBirthDate
        {
            get { return dtpInfoBirthDate.Value; }
            set { dtpInfoBirthDate.Value = value; }
        }
        public string InfoContactComments
        {
            get { return txtInfoComments.Text; }
            set { txtInfoComments.Text = value; }
        }
        public byte[] InfoContactImage
        {
            get { return Utils.ImageToBinary(pbxInfoPicture.Image); }
            set { pbxInfoPicture.Image = Utils.BinaryToImage(value); }
        }
        public string InfoAddressStreet
        {
            get { return txtInfoAddress.Text; }
            set { txtInfoAddress.Text = value; }
        }
        public string InfoAddressCity
        {
            get { return txtInfoCity.Text; }
            set { txtInfoCity.Text = value; }
        }
        public string InfoAddressPostalCode
        {
            get { return txtInfoPostalCode.Text; }
            set { txtInfoPostalCode.Text = value; }
        }
        public string InfoAddressCountry
        {
            get { return txtInfoCountry.Text; }
            set { txtInfoCountry.Text = value; }
        }
        public short InfoAddressType
        {
            get { return (short)cbxInfoAddressType.SelectedValue; }
            set { cbxInfoAddressType.SelectedValue = value; }
        }

        public string InfoPhoneNumber
        {
            get { return txtInfoPhoneNumber.Text; }
            set { txtInfoPhoneNumber.Text = value; }
        }
        public short InfoPhoneType
        {
            get { return (short)cbxInfoPhoneType.SelectedValue; }
            set { cbxInfoPhoneType.SelectedValue = value; }
        }
        public string InfoEmailAddress
        {
            get { return txtInfoEmailAddress.Text; }
            set { txtInfoEmailAddress.Text = value; }
        }
        public short InfoEmailType
        {
            get { return (short)cbxInfoEmailType.SelectedValue; }
            set { cbxInfoEmailType.SelectedValue = value; }
        }
        public string InfoGroupMemberCount
        {
            set { lblInfoGroupsMemberCount.Text = value; }
        }

        public bool EnableAddressAdd { set { lnkInfoAddAddress.Enabled = value; } }
        public bool EnableAddressModify { set { lnkInfoModifyAddress.Enabled = value; } }
        public bool EnableAddressRemove { set { lnkRemoveAddress.Enabled = value; } }
        public bool EnableEmailAdd { set { lnkInfoAddEmail.Enabled = value; } }
        public bool EnableEmailModify { set { lnkInfoModifyEmail.Enabled = value; } }
        public bool EnableEmailRemove { set { lnkInfoRemoveEmail.Enabled = value; } }
        public bool EnablePhoneAdd { set { lnkInfoAddPhone.Enabled = value; } }
        public bool EnablePhoneModify { set { lnkInfoModifyPhone.Enabled = value; } }
        public bool EnablePhoneRemove { set { lnkInfoRemovePhone.Enabled = value; } }
        
        #endregion

        public frmMain()
        {
            InitializeComponent();
            _presenter = new MainPresenter(this);
        }

        public void LoadFields()
        {
            cbxSearchEmailType.DataSource = _emailTypes;
            cbxSearchEmailType.DisplayMember = "Text";
            cbxSearchEmailType.ValueMember = "Value";

            cbxSearchPhoneType.DataSource = _phoneTypes;
            cbxSearchPhoneType.DisplayMember = "Text";
            cbxSearchPhoneType.ValueMember = "Value";

            cbxInfoAddressType.DataSource = _addressTypes;
            cbxInfoAddressType.DisplayMember = "Text";
            cbxInfoAddressType.ValueMember = "Value";

            cbxInfoEmailType.DataSource = _emailTypes;
            cbxInfoEmailType.DisplayMember = "Text";
            cbxInfoEmailType.ValueMember = "Value";

            cbxInfoPhoneType.DataSource = _phoneTypes;
            cbxInfoPhoneType.DisplayMember = "Text";
            cbxInfoPhoneType.ValueMember = "Value";

            cbxGroups.DataSource = _contactGroups;
            cbxGroups.DisplayMember = "Text";
            cbxGroups.ValueMember = "Value";

            lbxGroups.DisplayMember = "Text";
            lbxGroups.ValueMember = "Value";
            lbxGroups.DataSource = _groups;

        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            this._presenter.Load();
            this._presenter.SwitchToSearchTab();
        }
        public void BoldSearchButton()
        {
            this.btnSearch.Font = boldFont;
            this.btnInfo.Font = normalFont;
        }
        public void BoldInfoButton()
        {
            this.btnInfo.Font = boldFont;
            this.btnSearch.Font = normalFont;
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            this._presenter.SwitchToSearchTab();
        }

        private void btnInfo_Click(object sender, EventArgs e)
        {
            this._presenter.SwitchToInfoTab();
        }

        public void UpdateContacts()
        {
            lbxInfoContacts.DisplayMember = "Display";
            lbxInfoContacts.DataSource = _contacts;
        }

        public void UpdateFoundContacts()
        {
            lbxFoundContacts.DisplayMember = "Display";
            lbxFoundContacts.DataSource = _foundContacts;
        }
        public void UpdateFoundAddresses()
        {
            lbxFoundAddresses.DisplayMember = "AddressType";
            lbxFoundAddresses.DataSource = _foundAddresses;
        }
        public void UpdateFoundPhones()
        {
            lbxFoundPhones.DisplayMember = "PhoneType";
            lbxFoundPhones.DataSource = _foundPhones;
        }
        public void UpdateFoundEmails()
        {
            lbxFoundEmails.DisplayMember = "EmailType";
            lbxFoundEmails.DataSource = _foundEmails;
        }
        public void UpdateFoundGroups()
        {
            lbxFoundGroups.DisplayMember = "GroupName";
            lbxFoundGroups.DataSource = _foundGroups;
        }

        public void UpdateInfoAddresses()
        {
            lbxInfoAddresses.DisplayMember = "AddressType";
            lbxInfoAddresses.DataSource = _infoAddresses;
        }
        public void UpdateInfoPhones()
        {
            lbxInfoPhones.DisplayMember = "PhoneType";
            lbxInfoPhones.DataSource = _infoPhones;
        }
        public void UpdateInfoEmails()
        {
            lbxInfoEmails.DisplayMember = "EmailType";
            lbxInfoEmails.DataSource = _infoEmails;
        }
        public void UpdateInfoGroups()
        {
            lbxInfoGroups.DisplayMember = "GroupName";
            lbxInfoGroups.DataSource = _infoGroups;
        }

        public int SelectedContactId
        {
            get
            {
                if (lbxFoundContacts.SelectedValue != null)
                    return ((UIContact)lbxFoundContacts.SelectedValue).Id;
                return -1;
            }
        }

        public int SelectedInfoContactId
        {
            get
            {
                if (lbxInfoContacts.SelectedValue != null)
                    return ((UIContact)lbxInfoContacts.SelectedValue).Id;
                return -1;
            }
            set { lbxInfoContacts.SelectedIndex = -1; }
        }

        private void lbxFoundContacts_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.GetContactByIdForSearch();
        }
        private void lbxFoundAddresses_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedFoundAddress();
        }
        private void lbxFoundPhones_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedFoundPhone();
        }
        private void lbxFoundEmails_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedFoundEmails();
        }

        private void lnkSearchByPhone_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetContactsByPhone();
        }

        private void lnkSearchByNames_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetContactByNames();
        }

        private void lnkSearchByEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetContactByEmail();
        }

        #region Search by BirthDay Behavoir
        private void chkSearchToday_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSearchToday.Checked)
            {
                chkSearchThisWeek.Checked = false;
                chkSearchNextMonth.Checked = false;
            }
        }
        private void chkSearchThisWeek_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSearchThisWeek.Checked)
            {
                chkSearchToday.Checked = false;
                chkSearchNextMonth.Checked = false;
            }
        }
        private void chkSearchNextMonth_CheckedChanged(object sender, EventArgs e)
        {
            if (chkSearchNextMonth.Checked)
            {
                chkSearchThisWeek.Checked = false;
                chkSearchToday.Checked = false;
            }
        }
        #endregion

        private void lnkSearchByBirthDate_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetContactByBirthDate();
        }

        private void lbxFoundGroups_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedFoundGroups();
        }

        private void lnkSearchModifyUserData_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.SwitchToModifyUser();
        }


        private void lbxInfoPhones_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedInfoPhone();
        }

        private void lbxInfoEmails_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedInfoEmails();
        }

        private void lbxInfoGroups_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedInfoGroups();
        }

        private void lbxInfoAddresses_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.DisplaySelectedInfoAddress();
        }

        private void pbxInfoPicture_Click(object sender, EventArgs e)
        {
            this.ofdInfoPicture.ShowDialog();
        }

        private void ofdInfoPicture_FileOk(object sender, CancelEventArgs e)
        {
            this._presenter.SetContactImage();
            this.pbxInfoPicture.Refresh();
        }

        private void lnkInfoEditData_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.SaveContact();
        }

        private void lnkInfoAddAddress_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.AddAddress();
        }

        private void lnkInfoModifyAddress_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.EditAddress();
        }

        private void lnkInfoAddPhone_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.AddPhone();
        }

        private void lnkInfoModifyPhone_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.EditPhone();
        }

        private void lnkInfoAddEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.AddEmail();
        }

        private void lnkInfoModifyEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.EditEmail();
        }

        private void lnkRemoveAddress_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemoveAddress();
        }

        private void lnkDeletePhone_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemovePhone();
        }

        private void lnkRemoveEmail_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemoveEmail();
        }

        private void tmrChangeActualDate_Tick(object sender, EventArgs e)
        {
            lblActualDate.Text = string.Format("{0}, {1}", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString());
        }

        private void lbxGroups_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.GetContactsByGroup();
        }

        private void lnkAddContact_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.AddContact();
        }

        private void lbxInfoContacts_SelectedIndexChanged(object sender, EventArgs e)
        {
            this._presenter.GetContactByIdForInfo();
        }

        private void lnkInfoGroupAdd_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.AddGroupToContact();
        }

        private void lnkInfoGroupRemove_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemoveGroupFromContact();
        }

        private void lnkRemoveUser_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemoveContact();
        }

        private void lnkExport_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            if (sfdExport.ShowDialog() == DialogResult.OK)
            {
                this._presenter.ExportContacts();
            }
        }

        private void lnkAddGroup_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            using (frmGroups groups = new frmGroups())
            {
                groups.GroupId = -1;

                if (groups.ShowDialog() == DialogResult.OK)
                {
                    this._presenter.Load();
                }
            }
        }

        private void lnkModifyGroup_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            using (frmGroups groups = new frmGroups())
            {
                groups.GroupId = this.SelectedGroup;
                groups.GroupName = this.lbxGroups.Text;

                if (groups.ShowDialog() == DialogResult.OK)
                {
                    this._presenter.Load();
                }
            }
        }

        private void lnkRemoveGroup_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.RemoveGroup();
            this._presenter.Load();
        }

        private void linkShowAllUsers_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetAllContacts();
        }

        private void lnkShowGroupless_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            this._presenter.GetGrouplessContacts();
        }

    }
}
